package com.jinxin.platform.cddatadict.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jinxin.platform.base.common.pojo.JsonResult;
import com.jinxin.platform.cddatadict.mapper.CddatadictDictItemMapper;
import com.jinxin.platform.cddatadict.mapper.CddatadictDictTypeMapper;
import com.jinxin.platform.cddatadict.pojo.domains.DataDictItem;
import com.jinxin.platform.cddatadict.pojo.domains.DataDictType;
import com.jinxin.platform.cddatadict.pojo.entity.Constant;
import com.jinxin.platform.cddatadict.service.SysDictTypeService;
import com.jinxin.platform.cddatadict.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class SysDictTypeServiceImpl implements SysDictTypeService {
    @Autowired
    private CddatadictDictTypeMapper cddatadictDictTypeMapper;
    @Autowired
    private CddatadictDictItemMapper cddatadictDictItemMapper;
    @Value("${platform.upload}")
    private String uploadPath;

    @Override
    public int insert(DataDictType dataDictType) {
        return cddatadictDictTypeMapper.insert(dataDictType);
    }

    @Override
    public int updateByKey(DataDictType dataDictType) {
        return cddatadictDictTypeMapper.updateByKey(dataDictType);
    }

    @Override
    public DataDictType selectByKey(String id) {
        return cddatadictDictTypeMapper.selectByKey(id);
    }

    @Override
    public DataDictType selectOne(HashMap param) {
        return cddatadictDictTypeMapper.selectOne(param);
    }

    @Override
    public List<DataDictType> list(HashMap param) {
        return cddatadictDictTypeMapper.list(param);
    }

    @Override
    public List<DataDictType> listPage(HashMap param) {
        return cddatadictDictTypeMapper.listPage(param);
    }

    @Override
    public int listPageCount(HashMap param) {
        return cddatadictDictTypeMapper.listPageCount(param);
    }

    @Override
    public int deleteByKey(String id) {
        return cddatadictDictTypeMapper.deleteByKey(id);
    }

    @Override
    public JsonResult importDict(MultipartFile multipartFile) {
        int sCount = 0,uCount = 0;
        try {
            // 获取原始名字
            String fileName = multipartFile.getOriginalFilename();
            if(StringUtils.isEmpty(fileName)){
                return JsonResult.error("文件不存在");
            }
            String newFileName = DateUtil.getCurrentYMDHMS()+".json";
            // 获取后缀名
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            //先将.json文件转为字符串类型
            File file = new File(this.uploadPath + Constant.UPLOAD_FILE_MIDDLE_PATH + newFileName);
            //将MultipartFile类型转换为File类型
            FileUtils.copyInputStreamToFile(multipartFile.getInputStream(),file);
            String jsonString = FileUtils.readFileToString(file, "UTF-8");
            //如果是json或者txt文件
            if (".json".equals(suffixName) || ".txt".equals(suffixName)) {
                JSONArray jsonArray = JSONArray.parseArray(jsonString);
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    DataDictType dataDictType = JSONObject.toJavaObject(jsonObject, DataDictType.class);
                    String dictTypeId = dataDictType.getId();
                    if(StringUtils.isEmpty(dictTypeId)){continue;}
                    DataDictType dictType = cddatadictDictTypeMapper.selectByKey(dictTypeId);
                    if(dictType == null){
                        cddatadictDictTypeMapper.insert(dataDictType);
                    }else {
                        cddatadictDictTypeMapper.updateByKey(dataDictType);
                    }
                    JSONArray itemJsonArray = dataDictType.getItemJsonArray();
                    for (int j = 0; j < itemJsonArray.size(); j++) {
                        JSONObject jsonObject2 = itemJsonArray.getJSONObject(j);
                        DataDictItem dataDictItem = JSONObject.toJavaObject(jsonObject2, DataDictItem.class);
                        JSONArray jsonArray2 = dataDictItem.getItemJsonArray();
                        if(jsonArray2 != null && jsonArray2.size() > 0){
                            for (int k = 0; k < jsonArray2.size(); k++) {
                                JSONObject jsonObject3 = jsonArray2.getJSONObject(k);
                                DataDictItem dataDictItem2 = JSONObject.toJavaObject(jsonObject3, DataDictItem.class);
                                String dictItemId = dataDictItem2.getId();
                                if(StringUtils.isEmpty(dictItemId)){continue;}
                                DataDictItem dictItem = cddatadictDictItemMapper.selectByKey(dictItemId);
                                if(dictItem == null){
                                    sCount += cddatadictDictItemMapper.insert(dataDictItem2);
                                }else {
                                    uCount += cddatadictDictItemMapper.updateByKey(dataDictItem2);
                                }
                            }
                        }
                        String id = dataDictItem.getId();
                        if(StringUtils.isEmpty(id)){continue;}
                        DataDictItem dataDictItem2 = cddatadictDictItemMapper.selectByKey(id);
                        if(dataDictItem2 == null){
                            sCount += cddatadictDictItemMapper.insert(dataDictItem);
                        }else {
                            uCount += cddatadictDictItemMapper.updateByKey(dataDictItem);
                        }
                    }

                }
                log.info("导入json成功,删除文件");
                if(file.exists()){
                    file.delete();
                }
            } else {
                return JsonResult.error("请上传正确格式的json或txt文件");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JsonResult.ok("成功导入"+sCount+"条记录，修改"+uCount+"条记录",null);
    }

    @Override
    public JsonResult exportDict(HttpServletResponse response, String fileName) {
        if(StringUtils.isEmpty(fileName)){
            return JsonResult.error("文件名为空");
        }
        List<DataDictType> typeList = cddatadictDictTypeMapper.list(new HashMap());
        if(typeList.size() == 0){
            return JsonResult.error("数据字典类型不存在");
        }
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            JSONArray jsonArray = new JSONArray();
            for (int i = 0; i < typeList.size(); i++) {
                DataDictType dictType = typeList.get(i);
                if(dictType == null){continue;}
                String jsonString = objectMapper.writeValueAsString(dictType);
                JSONObject jsonObject = JSONObject.parseObject(jsonFormat(jsonString));
                HashMap param = new HashMap();
                param.put("dictType",dictType.getId());
                List<DataDictItem> dictItems = cddatadictDictItemMapper.list(param);
                JSONArray jsonArray2 = new JSONArray();
                for (int j = 0; j < dictItems.size(); j++) {
                    DataDictItem dataDictItem = dictItems.get(j);
                    if(dataDictItem == null){continue;}
                    String jsonString2 = objectMapper.writeValueAsString(dataDictItem);
                    JSONObject jsonObject2 = JSONObject.parseObject(jsonFormat(jsonString2));
                    // 第三级
                    HashMap param2 = new HashMap();
                    param.put("dictType",dataDictItem.getId());
                    List<DataDictItem> dictItems2 = cddatadictDictItemMapper.list(param);
                    if(dictItems2.size() > 0){
                        JSONArray jsonArray3 = new JSONArray();
                        for (int k = 0; k < dictItems2.size(); k++) {
                            DataDictItem dataDictItem2 = dictItems2.get(k);
                            if(dataDictItem2 == null){continue;}
                            String jsonString3 = objectMapper.writeValueAsString(dataDictItem2);
                            JSONObject jsonObject3 = JSONObject.parseObject(jsonFormat(jsonString3));
                            jsonArray3.add(jsonObject3);
                        }
                        jsonObject2.put("itemJsonArray",jsonArray3);
                    }
                    jsonArray2.add(jsonObject2);
                }
                jsonObject.put("itemJsonArray",jsonArray2);
                jsonArray.add(jsonObject);
            }
            log.info("拼接文件完整路径,生成json格式文件");
            String fullPath = this.uploadPath + Constant.UPLOAD_FILE_MIDDLE_PATH + fileName;
            // 保证创建一个新文件
            File file = new File(fullPath);
            if (!file.getParentFile().exists()) { // 如果父目录不存在，创建父目录
                file.getParentFile().mkdirs();
            }
            if (file.exists()) { // 如果已存在,删除旧文件
                file.delete();
            }
            file.createNewFile();//创建新文件

            //将字符串格式化为json格式
            // 将格式化后的字符串写入文件
            Writer write = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
            write.write(jsonArray.toJSONString());
            write.flush();
            write.close();

            FileInputStream fis = new FileInputStream(file);
            // 设置相关格式
            response.setContentType("application/force-download");
            // 设置下载后的文件名以及header
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
            response.setCharacterEncoding("utf-8");
            // 创建输出对象
            OutputStream os = response.getOutputStream();
            // 常规操作
            byte[] buf = new byte[1024];
            int len = 0;
            while((len = fis.read(buf)) != -1) {
                os.write(buf, 0, len);
            }
            fis.close();
            os.close();
            //一定要记得关闭输出流，不然会继续写入返回实体模型
            log.info("导出json成功,删除文件");
            if(file.exists()){
                file.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error(e.getMessage());
        }
        return null; //返回null
    }
    //将字符串格式化为json格式的字符串
    private static String jsonFormat(String jsonString) {
        JSONObject object= JSONObject.parseObject(jsonString);
        jsonString = JSON.toJSONString(object, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);
        return jsonString;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult deleteAll() {
        cddatadictDictTypeMapper.deleteAll();
        cddatadictDictItemMapper.deleteAll();
        return JsonResult.ok("删除成功",null);
    }

    @Override
    public JsonResult exportDict2(HttpServletResponse response, String fileName) {
        if(StringUtils.isEmpty(fileName)){
            return JsonResult.error("文件名为空");
        }
        List<DataDictType> typeList = cddatadictDictTypeMapper.list(new HashMap());
        if(typeList.isEmpty()){
            return JsonResult.error("数据字典类型不存在");
        }
        JSONObject jsonObject = new JSONObject();
        JSONArray typeJsonArray = JSONArray.parseArray(JSON.toJSONString(typeList));
        jsonObject.put("typeJsonArray",typeJsonArray);
        List<DataDictItem> dictItems = cddatadictDictItemMapper.list(new HashMap());
        JSONArray itemJsonArray = JSONArray.parseArray(JSON.toJSONString(dictItems));
        jsonObject.put("itemJsonArray",itemJsonArray);
        try {
            log.info("拼接文件完整路径,生成json格式文件");
            String fullPath = this.uploadPath + Constant.UPLOAD_FILE_MIDDLE_PATH + fileName;
            // 保证创建一个新文件
            File file = new File(fullPath);
            if (!file.getParentFile().exists()) { // 如果父目录不存在，创建父目录
                file.getParentFile().mkdirs();
            }
            if (file.exists()) { // 如果已存在,删除旧文件
                file.delete();
            }
            file.createNewFile();//创建新文件

            //将字符串格式化为json格式
            // 将格式化后的字符串写入文件
            Writer write = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
            write.write(jsonObject.toJSONString());
            write.flush();
            write.close();

            FileInputStream fis = new FileInputStream(file);
            // 设置相关格式
            response.setContentType("application/force-download");
            // 设置下载后的文件名以及header
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
            response.setCharacterEncoding("utf-8");
            // 创建输出对象
            OutputStream os = response.getOutputStream();
            // 常规操作
            byte[] buf = new byte[1024];
            int len = 0;
            while((len = fis.read(buf)) != -1) {
                os.write(buf, 0, len);
            }
            fis.close();
            os.close();
            //一定要记得关闭输出流，不然会继续写入返回实体模型
            log.info("导出json成功,删除文件");
            if(file.exists()){
                file.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error(e.getMessage());
        }
        return null;
    }

    @Override
    public JsonResult importDict2(MultipartFile multipartFile) {
        int addType = 0,editType = 0,addItem = 0,editItem = 0;
        try {
            // 获取原始名字
            String fileName = multipartFile.getOriginalFilename();
            if(StringUtils.isEmpty(fileName)){
                return JsonResult.error("文件不存在");
            }
            String newFileName = DateUtil.getCurrentYMDHMS()+".json";
            // 获取后缀名
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            //先将.json文件转为字符串类型
            File file = new File(this.uploadPath + Constant.UPLOAD_FILE_MIDDLE_PATH + newFileName);
            //将MultipartFile类型转换为File类型
            FileUtils.copyInputStreamToFile(multipartFile.getInputStream(),file);
            String jsonString = FileUtils.readFileToString(file, "UTF-8");
            //如果是json或者txt文件
            if (".json".equals(suffixName) || ".txt".equals(suffixName)) {
                JSONObject jsonObj = JSONObject.parseObject(jsonString);
                JSONArray typeJsonArray = jsonObj.getJSONArray("typeJsonArray");
                for (int i = 0; i < typeJsonArray.size(); i++) {
                    JSONObject jsonObject = typeJsonArray.getJSONObject(i);
                    DataDictType dataDictType = JSONObject.toJavaObject(jsonObject, DataDictType.class);
                    String dictTypeId = dataDictType.getId();
                    if(StringUtils.isEmpty(dictTypeId)){continue;}
                    DataDictType dictType = cddatadictDictTypeMapper.selectByKey(dictTypeId);
                    if(dictType == null){
                        addType += cddatadictDictTypeMapper.insert(dataDictType);
                    }else {
                        editType += cddatadictDictTypeMapper.updateByKey(dataDictType);
                    }
                }
                JSONArray itemJsonArray = jsonObj.getJSONArray("itemJsonArray");
                for (int i = 0; i < itemJsonArray.size(); i++) {
                    JSONObject jsonObject = itemJsonArray.getJSONObject(i);
                    DataDictItem dataDictType = JSONObject.toJavaObject(jsonObject, DataDictItem.class);
                    String dictTypeId = dataDictType.getId();
                    if(StringUtils.isEmpty(dictTypeId)){continue;}
                    DataDictItem dictItem = cddatadictDictItemMapper.selectByKey(dictTypeId);
                    if(dictItem == null){
                        addItem += cddatadictDictItemMapper.insert(dataDictType);
                    }else {
                        editItem += cddatadictDictItemMapper.updateByKey(dataDictType);
                    }
                }
                log.info("导入json成功,删除文件");
                if(file.exists()){
                    file.delete();
                }
            } else {
                return JsonResult.error("请上传正确格式的json或txt文件");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JsonResult.ok("成功导入"+addType+"个类型，"+addItem+"个字典项，" +
                "修改"+editType+"个类型，"+editItem+"个字典项",null);
    }
}
